/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.netbeans.modules.lsp.client.options;

import java.util.ArrayList;
import java.util.List;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import javax.swing.JCheckBox;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import org.openide.util.Exceptions;

public class MarkOccurencesPanel extends javax.swing.JPanel {

    private static final boolean DEFAULT_VALUE = true; // May need to be splited if the defaunts ar not all on

    private List<JCheckBox> boxes;
    private MarkOccurencesOptionsPanelController controller;
    private boolean changed = false;

    /** Creates new form MarkOccurencesPanel */
    public MarkOccurencesPanel( MarkOccurencesOptionsPanelController controller ) {
        initComponents();
        fillBoxes();
        addListeners();
        load( controller );
    }

    public void load( MarkOccurencesOptionsPanelController controller ) {
        this.controller = controller;

        Preferences node = MarkOccurencesSettings.getCurrentNode();

        for (JCheckBox box : boxes) {
            box.setSelected(node.getBoolean(box.getActionCommand(), DEFAULT_VALUE));
        }

        componentsSetEnabled();
        changed = false;
    }

    public void store( ) {
        Preferences node = MarkOccurencesSettings.getCurrentNode();

        for (javax.swing.JCheckBox box : boxes) {
            boolean value = box.isSelected();
            boolean original = node.getBoolean(box.getActionCommand(),
                                               DEFAULT_VALUE);

            if (value != original) {
                node.putBoolean(box.getActionCommand(), value);
            }
        }
        try {
            node.flush();
        }
        catch (BackingStoreException ex) {
            Exceptions.printStackTrace(ex);
        }
        changed = false;
}

    public boolean changed() {
        return changed;
    }


    /** This method is called from within the constructor to
     * initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is
     * always regenerated by the Form Editor.
     */
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {
        java.awt.GridBagConstraints gridBagConstraints;

        onOffCheckBox = new javax.swing.JCheckBox();
        keepMarks = new javax.swing.JCheckBox();

        setBorder(javax.swing.BorderFactory.createEmptyBorder(8, 8, 8, 8));
        setLayout(new java.awt.GridBagLayout());

        org.openide.awt.Mnemonics.setLocalizedText(onOffCheckBox, org.openide.util.NbBundle.getMessage(MarkOccurencesPanel.class, "CTL_OnOff_CheckBox")); // NOI18N
        onOffCheckBox.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        onOffCheckBox.setMargin(new java.awt.Insets(0, 0, 0, 0));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weightx = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 0, 12, 0);
        add(onOffCheckBox, gridBagConstraints);
        onOffCheckBox.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(MarkOccurencesPanel.class, "ACSD_OnOff_CB")); // NOI18N

        org.openide.awt.Mnemonics.setLocalizedText(keepMarks, org.openide.util.NbBundle.getBundle(MarkOccurencesPanel.class).getString("CTL_KeepMarks_CheckBox")); // NOI18N
        keepMarks.setBorder(javax.swing.BorderFactory.createEmptyBorder(0, 0, 0, 0));
        keepMarks.setMargin(new java.awt.Insets(0, 0, 0, 0));
        gridBagConstraints = new java.awt.GridBagConstraints();
        gridBagConstraints.gridwidth = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.gridheight = java.awt.GridBagConstraints.REMAINDER;
        gridBagConstraints.anchor = java.awt.GridBagConstraints.NORTHWEST;
        gridBagConstraints.weighty = 1.0;
        gridBagConstraints.insets = new java.awt.Insets(0, 20, 8, 0);
        add(keepMarks, gridBagConstraints);
        keepMarks.getAccessibleContext().setAccessibleDescription(org.openide.util.NbBundle.getMessage(MarkOccurencesPanel.class, "ACSD_Marks_CB")); // NOI18N
    }// </editor-fold>//GEN-END:initComponents


    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JCheckBox keepMarks;
    private javax.swing.JCheckBox onOffCheckBox;
    // End of variables declaration//GEN-END:variables
    // End of variables declaration


    private void fillBoxes() {
        boxes = new ArrayList<JCheckBox>();
        boxes.add( onOffCheckBox );
        boxes.add( keepMarks );

        onOffCheckBox.setActionCommand(MarkOccurencesSettingsNames.ON_OFF);
        keepMarks.setActionCommand(MarkOccurencesSettingsNames.KEEP_MARKS);
    }


    private void addListeners() {
        ChangeListener cl = new CheckChangeListener();

        for( JCheckBox box : boxes ) {
            box.addChangeListener(cl);
        }

    }

    private void componentsSetEnabled() {
        for( int i = 1; i < boxes.size(); i++ ) {
            boxes.get(i).setEnabled(onOffCheckBox.isSelected()); // Switch off the other boxes
        }
    }

    private void fireChanged() {
        Preferences node = MarkOccurencesSettings.getCurrentNode();
        for (JCheckBox box : boxes) {
            if (node.getBoolean(box.getActionCommand(), DEFAULT_VALUE) != box.isSelected()) {
                changed = true;
                return;
            }
        }
        changed = false;
    }

    private class CheckChangeListener implements ChangeListener {

        @Override
        public void stateChanged(ChangeEvent evt) {
            if (evt.getSource().equals(onOffCheckBox)) {
                componentsSetEnabled();
            }
            fireChanged();
        }
    }

}
